package com.example.room.database;

import android.content.Context;

import androidx.annotation.NonNull;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.room.migration.Migration;
import androidx.sqlite.db.SupportSQLiteDatabase;

import com.example.room.dao.StudentDao;
import com.example.room.entity.Student;

//当exportSchema为true时 则会创建一个json文件用于保存数据库的信息
//json文件保存了数据库每次变更的情况
//在gradle文件中加入以下代码 用于指定数据库文件导出位置
/* javaCompileOptions{
         annotationProcessorOptions{
         arguments = ["room.schemaLocation":"$projectDir/schemas".toString()]//指出数据库信息导出位置
         }
}*/
@Database(entities = {Student.class}, version = 4, exportSchema = true)
//该类用于创建数据库并且得到Dao对象 必须是一个抽象类
public abstract class StudentDataBase extends RoomDatabase {

    private static StudentDataBase dataBase;
    //数据库名称
    private static final String DB_NAME = "student.db";

    //单例模式
    public static synchronized StudentDataBase getInstance(Context context) {
        if (dataBase == null) {
            dataBase = Room.databaseBuilder(context.getApplicationContext(), StudentDataBase.class, DB_NAME)
                    //升级数据库
                    .addMigrations(MIGRATION_1_2, MIGRATION_2_3 , MIGRATION_3_4)
                    //当升级数据库失败时会抛出异常，此方法会继续运行app 重新创建表项 同时之前的数据会清空
                    //.fallbackToDestructiveMigration()
                    .build();
        }
        return dataBase;
    }

    //需要一个获取DAO对象的抽象方法
    public abstract StudentDao getDao();


    //利用Migration升级数据库
    //如果从1升级到3 数据库首先会判断有没有从1直接到3的方案 如果有就直接执行
    //如果没有则执行1到2 2到3的方案
    static final Migration MIGRATION_1_2 = new Migration(1, 2) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            //添加一个属性
            database.execSQL("ALTER TABLE student ADD COLUMN sex INTEGER NOT NULL DEFAULT 1");
        }
    };

    static final Migration MIGRATION_2_3 = new Migration(2, 3) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            //添加一个属性
            database.execSQL("ALTER TABLE student ADD COLUMN bar_data INTEGER NOT NULL DEFAULT 1");
        }
    };

    //销毁与重建策略
    //想把表中的sex的integer属性改为text
    //1创建一个临时表temp_student
    //2将student表中的数据导入到temp_student表中
    //3删除student表
    //4重命名temp_student表为student
    static final Migration MIGRATION_3_4 = new Migration(3, 4) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            //1创建一个临时表temp_student
            database.execSQL("CREATE TABLE temp_student (" +
                    "id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " +
                    "name TEXT," +
                    "age INTEGER NOT NULL," +
                    "sex TEXT DEFAULT 'M'," +
                    "bar_data INTEGER NOT NULL)");
            //2将student表中的数据导入到temp_student表中
            database.execSQL("INSERT INTO temp_student (name , age , sex , bar_data)" +
                    "SELECT name ,age, sex, bar_data FROM student");
            //3删除student表
            database.execSQL("DROP TABLE student");
            //4重命名temp_student表为student
            database.execSQL("ALTER TABLE temp_student RENAME TO student");
        }
    };
}
